package com.liu.yubi.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.rholder.retry.Retryer;
import com.liu.yubi.annotation.AuthCheck;
import com.liu.yubi.common.BaseResponse;
import com.liu.yubi.common.DeleteRequest;
import com.liu.yubi.common.ErrorCode;
import com.liu.yubi.common.ResultUtils;
import com.liu.yubi.constant.UserConstant;
import com.liu.yubi.exception.BusinessException;
import com.liu.yubi.exception.ThrowUtils;
import com.liu.yubi.manager.RedisLimiterManager;
import com.liu.yubi.model.dto.chart.*;
import com.liu.yubi.model.entity.Chart;
import com.liu.yubi.model.entity.User;
import com.liu.yubi.model.vo.BiResponse;
import com.liu.yubi.service.ChartService;
import com.liu.yubi.service.UserService;
import com.liu.yubi.utils.CopyUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import retrofit2.http.POST;
import retrofit2.http.Part;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.sound.midi.Track;

/**
 * 图表接口
 */
@RestController
@RequestMapping("/chart")
//@CrossOrigin(origins = {"http://localhost:8000"})
@Slf4j
public class ChartController {

    @Resource
    private UserService userService;

    @Resource
    private ChartService chartService;

    @Resource
    private RedisLimiterManager limiterManager;


    @Resource
    private Retryer<Boolean> retryer;


    /**
     *
     * @param chartAddRequest 新增图表请求类
     * @param request httpRequest
     */
    @PostMapping("/add")
    public BaseResponse<Long> addChart(@RequestBody ChartAddRequest chartAddRequest, HttpServletRequest request) {
        if (chartAddRequest == null) {
            throw new BusinessException (ErrorCode.PARAMS_ERROR, "请求参数有误！");
        }
        User loginUser = userService.getLoginUser (request);
        Chart chart = CopyUtils.copy (chartAddRequest, Chart.class);
        //关联用户信息
        chart.setUserId (loginUser.getId ());
        //限流
        limiterManager.doRateLimiter (loginUser.getId ().toString ());
        //保存数据
        boolean save = chartService.save (chart);
        if (!save) {
            throw new BusinessException (ErrorCode.OPERATION_ERROR);
        }
        return ResultUtils.success (chart.getId ());
        }

    /**
     * 删除图表(管理员和本人可以操作)
     * @param deleteRequest 删除请求
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteChart(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        //执行删除操作
        Boolean b = chartService.delete (deleteRequest,request);
        return ResultUtils.success (b);
    }

    /**
     * 更新图表
     * @param chartUpdateRequest 图表更新数据
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> updateChart(@RequestBody ChartUpdateRequest chartUpdateRequest) {
        if (chartUpdateRequest == null || chartUpdateRequest.getId() <= 0) {
            throw new BusinessException (ErrorCode.PARAMS_ERROR);
        }
        //执行操作
        Boolean res = chartService.updateChart (chartUpdateRequest);
        return ResultUtils.success (res);

    }

    /**
     * 根据 id 获取图表
     *
     */
    @GetMapping("/get")
    public BaseResponse<Chart> getChartById(@RequestParam  long id) {
        if (id <= 0) {
            throw new BusinessException (ErrorCode.PARAMS_ERROR);
        }
        Chart chart = chartService.getById (id);
        ThrowUtils.throwIf (chart==null, ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success (chart);
    }
    /**
     * 分页获取图表列表（仅管理员）
     *
     * @param chartQueryRequest 图表查询请求类
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<Chart>> listChartByPage(@RequestBody ChartQueryRequest chartQueryRequest) {
        if (chartQueryRequest==null){
            throw new BusinessException (ErrorCode.PARAMS_ERROR);
        }
        //执行操作
        Page<Chart> chartPage = chartService.listChartByPage (chartQueryRequest);
        return ResultUtils.success(chartPage);
    }

    /**
     * 分页获取图表列表(当前用户)
     *
     * @param chartQueryRequest 图表查询请求类
     */
    @PostMapping("/my/list/page")
    public BaseResponse<Page<Chart>> listMyChartByPage(@RequestBody ChartQueryRequest chartQueryRequest,
                                                       HttpServletRequest request) {
        if (chartQueryRequest==null){
            throw new BusinessException (ErrorCode.PARAMS_ERROR);
        }
        long current = chartQueryRequest.getCurrent();
        long size = chartQueryRequest.getPageSize();
        //限制爬虫
        ThrowUtils.throwIf (size>20,ErrorCode.PARAMS_ERROR);
        //当前用户
        User loginUser = userService.getLoginUser (request);
        chartQueryRequest.setUserId (loginUser.getId ());
        Page<Chart> userPage = chartService.page(new Page<>(current, size),
                chartService.getQueryWrapper (chartQueryRequest));
        return ResultUtils.success(userPage);
    }

    /**
     *  编辑图表
     * @param chartEditRequest 编辑图表请求类
     */

    @PostMapping("/edit")
    public BaseResponse<Boolean> editChart(@RequestBody ChartEditRequest chartEditRequest, HttpServletRequest request) {
        if (chartEditRequest == null || chartEditRequest.getId() <= 0) {
            throw new BusinessException (ErrorCode.PARAMS_ERROR);
        }
        //当前登录用户
        User loginUser = userService.getLoginUser (request);
        //判断图表是否存在
        Chart chart = chartService.getById (chartEditRequest.getId ());
        ThrowUtils.throwIf (chart==null,ErrorCode.NOT_FOUND_ERROR);
        //本人和管理员可以编辑
        if (Boolean.TRUE.equals(!userService.isAdmin (request))&& !chart.getUserId ().equals (loginUser.getId ())) {
            throw new BusinessException (ErrorCode.NO_AUTH_ERROR);
        }
        //编辑图表
        Chart chart1 = CopyUtils.copy (chartEditRequest, Chart.class);
        boolean b = chartService.updateById (chart1);
        return ResultUtils.success (b);
    }

    /**
     *智能分析
     * @param file 原始数据
     * @param chartByAiRequest 分析数据
     */
    @PostMapping("/gen")
    public BaseResponse<BiResponse> genChartByAi(@RequestPart("file") MultipartFile file, GenChartByAiRequest chartByAiRequest,
                                                 HttpServletRequest request){
        //获取登录用户
        User loginUser = userService.getLoginUser (request);
        BiResponse biResponse = chartService.genChartByAi (file, chartByAiRequest, loginUser);
        return ResultUtils.success (biResponse);

    }
    @PostMapping("/gen/async")
    public BaseResponse<BiResponse> genChartByAiAsync(@RequestPart("file") MultipartFile file,GenChartByAiRequest aiRequest,
                                                      HttpServletRequest request){

        //获取当期用户
        User loginUser = userService.getLoginUser (request);
        //异步化执行
        Long chartId = chartService.genByAiAsync (file, aiRequest, loginUser);
        BiResponse biResponse = BiResponse.builder ()
                .chartId (chartId)
                .build ();
        return ResultUtils.success (biResponse);


    }

    @SneakyThrows
    @PostMapping("/gen/async/mq")
    public BaseResponse<BiResponse> genChartByAiAsyncMq(@RequestPart("file") MultipartFile file,
                                                        GenChartByAiRequest aiRequest, HttpServletRequest request){

        //获取当期用户
        User loginUser = userService.getLoginUser (request);
        //智能化分析
        Long chartID = chartService.genByAiMq (file, aiRequest, loginUser);
        BiResponse biResponse = BiResponse.builder ()
                .chartId (chartID)
                .build ();
        return ResultUtils.success (biResponse);

    }

    //重新生成图表
    @PostMapping("/regen")
    public BaseResponse<BiResponse> regenChart(@RequestBody ChartRegenRequest regenRequest,HttpServletRequest request){
        Long chartId = regenRequest.getId ();
        //校验参数
        if (chartId==null || chartId<=0){
            throw new BusinessException (ErrorCode.PARAMS_ERROR);
        }
        //执行重新生成操作
        BiResponse biResponse = chartService.regenChart (regenRequest, request);

        return ResultUtils.success (biResponse);

    }

    /**
     * 重新生成图表（Admin）
     */
    @PostMapping("/regen/by/admin")
    public BaseResponse<Boolean> regenChartByAsyncMqAdmin(@RequestBody ChartRegenRequest regenRequest,
                                                          HttpServletRequest request){
        if (regenRequest==null){
            throw new BusinessException (ErrorCode.PARAMS_ERROR);
        }
        System.out.println ("=================="+regenRequest.getId ()+"====================");
        Boolean result = chartService.regenChartByAsyncMqAdmin (regenRequest, request);
        return ResultUtils.success (result);
    }


}
